package org.jsola.hr.service.impl;

import org.jsola.common.StrKit;
import org.jsola.core.Page;
import org.jsola.exception.ParamException;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.constant.CalculatePayConstant;
import org.jsola.hr.constant.EmpInfoStatus;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.IEmpInfoDAO;
import org.jsola.hr.dao.ISalaryCalculateRuleGroupDAO;
import org.jsola.hr.dto.IssueSalaryCalculateRuleDTO;
import org.jsola.hr.dto.SalaryCalculateRuleAddDTO;
import org.jsola.hr.dto.SalaryCalculateRuleGroupAddDTO;
import org.jsola.hr.dto.SalaryCalculateRuleGroupUpdateDTO;
import org.jsola.hr.entity.*;
import org.jsola.hr.query.SalaryCalculateRuleEmpInfoQuery;
import org.jsola.hr.query.SalaryCalculateRuleGroupQuery;
import org.jsola.hr.service.*;
import org.jsola.hr.vo.EmpInfoVO;
import org.jsola.hr.vo.SalaryCalculateRuleGroupListVO;
import org.jsola.hr.vo.SalaryCalculateRuleGroupVO;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 工价计算规则组
 *
 * @author zhr
 */
@Service("hrSalaryCalculateRuleGroupServiceImpl")
public class SalaryCalculateRuleGroupServiceImpl implements ISalaryCalculateRuleGroupService {

    @Autowired
    private ISalaryCalculateRuleGroupDAO salaryCalculateRuleGroupDAO;
    @Autowired
    private ISalaryCalculateRuleService salaryCalculateRuleService;
    @Autowired
    private IEmpInfoService empInfoService;
    @Autowired
    private ICompanyService companyService;
    @Autowired
    private IEmpInfoDAO empInfoDAO;
    @Autowired
    private ICheckInPeopleService checkInPeopleService;
    @Autowired
    private IChannelService channelService;

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public SalaryCalculateRuleGroupVO save(SalaryCalculateRuleGroupAddDTO salaryCalculateRuleGroupAddDTO, TokenUser tokenUser) {
        // 转DO
        SalaryCalculateRuleGroupDO salaryCalculateRuleGroupDO = salaryCalculateRuleGroupAddDTO.to(SalaryCalculateRuleGroupDO.class);
        // 判断是否为租户新增
        if (StrKit.isEmpty(salaryCalculateRuleGroupDO.getCompanyId())
                || "0".equals(salaryCalculateRuleGroupDO.getCompanyId())) {
            salaryCalculateRuleGroupDO.setCompanyId(tokenUser.getSiteId());
        }
        // 校验是否名称重复
        SalaryCalculateRuleGroupDO salaryCalculateRuleGroup = this
                .selectByCompanyIdAndName(salaryCalculateRuleGroupDO.getCompanyId(), salaryCalculateRuleGroupDO.getName());
        if (Objects.nonNull(salaryCalculateRuleGroup)) {
            throw new ParamException("名称不能重复");
        }
        // 保存
        salaryCalculateRuleGroupDO = save(salaryCalculateRuleGroupDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return salaryCalculateRuleGroupDO.to(SalaryCalculateRuleGroupVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(SalaryCalculateRuleGroupUpdateDTO salaryCalculateRuleGroupUpdateDTO, TokenUser tokenUser) {
        //转DO
        SalaryCalculateRuleGroupDO salaryCalculateRuleGroupDO = salaryCalculateRuleGroupUpdateDTO.to(SalaryCalculateRuleGroupDO.class);
        // 判断是否为租户修改
        if ("0".equals(salaryCalculateRuleGroupDO.getCompanyId())) {
            salaryCalculateRuleGroupDO.setCompanyId(tokenUser.getSiteId());
            // 同时根据id查询来源为此规则组的规则组  来源设置为空
            setSourceIsNull(salaryCalculateRuleGroupUpdateDTO.getId(), tokenUser);
        }
        // 校验是否名称重复
        if (StrKit.isNotEmpty(salaryCalculateRuleGroupDO.getName())
                && StrKit.isNotEmpty(salaryCalculateRuleGroupDO.getCompanyId())) {
            SalaryCalculateRuleGroupDO salaryCalculateRuleGroup = this
                    .selectByCompanyIdAndName(salaryCalculateRuleGroupDO.getCompanyId(), salaryCalculateRuleGroupDO.getName());
            if (Objects.nonNull(salaryCalculateRuleGroup)
                    && !salaryCalculateRuleGroup.getId().equals(salaryCalculateRuleGroupDO.getId())) {
                throw new ParamException("名称不能重复");
            }
        }
        //根据主键更新，只更新非null值
        return updateByIdSelective(salaryCalculateRuleGroupDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void setSourceIsNull(String groupId, TokenUser tokenUser) {
        // 根据规则组id 查询来源是该规则组id的规则组
        List<SalaryCalculateRuleGroupDO> salaryCalculateRuleGroupDOList = this.selectBySource(groupId, tokenUser.getSiteId());
        if (CollectionUtils.isEmpty(salaryCalculateRuleGroupDOList)) {
            return;
        }
        // 修改这些规则组的来源为空
        for (SalaryCalculateRuleGroupDO salaryCalculateRuleGroupDO : salaryCalculateRuleGroupDOList) {
            salaryCalculateRuleGroupDO.setSource(null);
            this.updateById(salaryCalculateRuleGroupDO, tokenUser.getSiteId(), tokenUser.getUserId());
        }
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... salaryCalculateRuleGroupIds) {
        // 删除限制
        for (String salaryCalculateRuleGroupId : salaryCalculateRuleGroupIds) {
            SalaryCalculateRuleGroupDO salaryCalculateRuleGroupDO = this.selectDOById(salaryCalculateRuleGroupId, tokenUser.getSiteId());
            ParamException.notNull(salaryCalculateRuleGroupDO, "规则不存在或已被删除，请稍后重试");
            if (tokenUser.getSiteId().equals(salaryCalculateRuleGroupDO.getCompanyId())) {
                // 租户级别查询 所有用工单位的使用人数
                List<EmpInfoVO> empInfoVOList = selectSiteUseEmpInfoListVOByRuleTypeAndSalaryCalculateRuleId(salaryCalculateRuleGroupDO.getRuleType(),
                        salaryCalculateRuleGroupDO.getId(), null, tokenUser);
                ParamException.isTrue(CollectionUtils.isEmpty(empInfoVOList),
                        "规则" + salaryCalculateRuleGroupDO.getName() + "被使用中，无法删除，请先删除该规则的使用人员!");
            } else {
                // 用工单位级别展示本用工单位的规则的使用人数
                List<EmpInfoVO> empInfoVOList = selectCompanyUseEmpInfoListVOByRuleTypeAndSalaryCalculateRuleId(salaryCalculateRuleGroupDO.getRuleType(),
                        salaryCalculateRuleGroupDO.getId(), null, tokenUser);
                ParamException.isTrue(CollectionUtils.isEmpty(empInfoVOList),
                        "规则" + salaryCalculateRuleGroupDO.getName() + "被使用中，无法删除，请先删除该规则的使用人员!");
            }
        }
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) salaryCalculateRuleGroupIds);
    }


    @Override
    public SalaryCalculateRuleGroupVO selectById(String salaryCalculateRuleGroupId, String siteId) {
        SalaryCalculateRuleGroupDO salaryCalculateRuleGroupDO = selectDOById(salaryCalculateRuleGroupId, siteId);
        if (salaryCalculateRuleGroupDO == null) {
            return null;
        }
        return salaryCalculateRuleGroupDO.to(SalaryCalculateRuleGroupVO.class);
    }

    @Override
    public List<SalaryCalculateRuleGroupListVO> select(SalaryCalculateRuleGroupQuery salaryCalculateRuleGroupQuery, String siteId) {
        if (StrKit.isEmpty(salaryCalculateRuleGroupQuery.getCompanyId())
                || "0".equals(salaryCalculateRuleGroupQuery.getCompanyId())) {
            salaryCalculateRuleGroupQuery.setCompanyId(siteId);
        }
        List<SalaryCalculateRuleGroupDO> salaryCalculateRuleGroupDOList = selectDO(salaryCalculateRuleGroupQuery, siteId);
        if (CollectionUtils.isEmpty(salaryCalculateRuleGroupDOList)) {
            return salaryCalculateRuleGroupDOList == null ? null : new ArrayList<>();
        }
        return salaryCalculateRuleGroupDOList.stream()
                .map(salaryCalculateRuleGroupDO -> salaryCalculateRuleGroupDO.to(SalaryCalculateRuleGroupListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(SalaryCalculateRuleGroupQuery salaryCalculateRuleGroupQuery, String siteId) {
        Example example = buildExample(salaryCalculateRuleGroupQuery, siteId);
        return salaryCalculateRuleGroupDAO.selectCountByExample(example);
    }

    @Override
    public Page<SalaryCalculateRuleGroupListVO> selectPage(SalaryCalculateRuleGroupQuery salaryCalculateRuleGroupQuery, String siteId) {
        if (StrKit.isEmpty(salaryCalculateRuleGroupQuery.getCompanyId())
                || "0".equals(salaryCalculateRuleGroupQuery.getCompanyId())) {
            salaryCalculateRuleGroupQuery.setCompanyId(siteId);
        }
        Example example = buildExample(salaryCalculateRuleGroupQuery, siteId);
        Page<SalaryCalculateRuleGroupDO> page = salaryCalculateRuleGroupDAO.selectPageByExample(example,
                salaryCalculateRuleGroupQuery.getPageNo(),
                salaryCalculateRuleGroupQuery.getPageSize());

        return page.to(SalaryCalculateRuleGroupListVO.class);
    }

    @Override
    public SalaryCalculateRuleGroupDO selectDOById(String salaryCalculateRuleGroupId, String siteId) {
        return listById(salaryCalculateRuleGroupId, siteId);
    }

    @Override
    public List<SalaryCalculateRuleGroupDO> selectDO(SalaryCalculateRuleGroupQuery salaryCalculateRuleGroupQuery, String siteId) {
        Example example = buildExample(salaryCalculateRuleGroupQuery, siteId);
        return salaryCalculateRuleGroupDAO.selectByExample(example);
    }

    @Override
    public Integer issueGroup(IssueSalaryCalculateRuleDTO issueSalaryCalculateRuleDTO, TokenUser tokenUser) {
        if (CollectionUtils.isEmpty(issueSalaryCalculateRuleDTO.getCompanyIdList())
                || CollectionUtils.isEmpty(issueSalaryCalculateRuleDTO.getSalaryCalculateRuleGroupIdList())) {
            throw new ParamException("下发单位和规则都不能为空");
        }
        List<String> salaryCalculateRuleGroupIdList = issueSalaryCalculateRuleDTO.getSalaryCalculateRuleGroupIdList();
        List<String> companyIdList = issueSalaryCalculateRuleDTO.getCompanyIdList();
        // companyIdList去重
        companyIdList = companyIdList.stream().distinct().collect(Collectors.toList());
        for (String salaryCalculateRuleGroupId : salaryCalculateRuleGroupIdList) {
            // 复制规则组到单位中
            SalaryCalculateRuleGroupDO salaryCalculateRuleGroupDO = this
                    .selectDOById(salaryCalculateRuleGroupId, tokenUser.getSiteId());
            SalaryCalculateRuleGroupAddDTO salaryCalculateRuleGroupAddDTO = salaryCalculateRuleGroupDO
                    .to(SalaryCalculateRuleGroupAddDTO.class);
            // 查找该规则组的所有规则
            List<SalaryCalculateRuleDO> salaryCalculateRuleDOList = salaryCalculateRuleService
                    .selectByGroupId(salaryCalculateRuleGroupId, tokenUser);
            for (String companyId : companyIdList) {
                // 根据当前复制的规则组名称查找该单位的规则组
                String name = salaryCalculateRuleGroupAddDTO.getName();
                SalaryCalculateRuleGroupDO salaryCalculateRuleGroup = selectByCompanyIdAndName(companyId, name);
                String newSalaryCalculateRuleGroupId = "";
                if (Objects.isNull(salaryCalculateRuleGroup)) {
                    // 新增
                    salaryCalculateRuleGroupAddDTO.setCompanyId(companyId);
                    salaryCalculateRuleGroupAddDTO.setSource(salaryCalculateRuleGroupId);
                    newSalaryCalculateRuleGroupId = this.save(salaryCalculateRuleGroupAddDTO, tokenUser).getId();
                } else {
                    newSalaryCalculateRuleGroupId = salaryCalculateRuleGroup.getId();
                    // 修改用工单位的规则组来源
                    SalaryCalculateRuleGroupUpdateDTO salaryCalculateRuleGroupUpdateDTO = new SalaryCalculateRuleGroupUpdateDTO();
                    salaryCalculateRuleGroupUpdateDTO.setId(salaryCalculateRuleGroup.getId());
                    salaryCalculateRuleGroupUpdateDTO.setSource(salaryCalculateRuleGroupId);
                    salaryCalculateRuleGroupUpdateDTO.setRuleType(salaryCalculateRuleGroupAddDTO.getRuleType());
                    this.update(salaryCalculateRuleGroupUpdateDTO, tokenUser);
                    // 删除用工单位的规则组里面的所有规则
                    List<SalaryCalculateRuleDO> salaryCalculateRuleDelete = salaryCalculateRuleService
                            .selectByGroupId(newSalaryCalculateRuleGroupId, tokenUser);
                    if (!CollectionUtils.isEmpty(salaryCalculateRuleDelete)) {
                        String[] deleteIds = salaryCalculateRuleDelete.stream().map(SalaryCalculateRuleDO::getId)
                                .collect(Collectors.toList()).toArray(new String[salaryCalculateRuleDelete.size()]);
                        salaryCalculateRuleService.deleteByIds(tokenUser, deleteIds);
                    }
                }
                if (CollectionUtils.isEmpty(salaryCalculateRuleDOList)) {
                    continue;
                }
                // 复制规则到新的规则组中
                for (SalaryCalculateRuleDO salaryCalculateRuleDO : salaryCalculateRuleDOList) {
                    SalaryCalculateRuleAddDTO salaryCalculateRuleAddDTO = salaryCalculateRuleDO
                            .to(SalaryCalculateRuleAddDTO.class);
                    salaryCalculateRuleAddDTO.setSalaryCalculateRuleGroupId(newSalaryCalculateRuleGroupId);
                    salaryCalculateRuleService.save(salaryCalculateRuleAddDTO, tokenUser);
                }


            }
        }
        return salaryCalculateRuleGroupIdList.size() * companyIdList.size();
    }

    @Override
    public void setUsePeopleNumber(SalaryCalculateRuleGroupListVO salaryCalculateRuleGroupListVO, TokenUser tokenUser) {
        // 根据规则id查询员工信息表里使用的人数
        int number = 0;
        if (tokenUser.getSiteId().equals(salaryCalculateRuleGroupListVO.getCompanyId())) {
            // 租户级别展示所有用工单位的使用人数
            number = selectSiteUseCountEmpInfoListVOByRuleTypeAndSalaryCalculateRuleId(salaryCalculateRuleGroupListVO.getRuleType(),
                    salaryCalculateRuleGroupListVO.getId(), tokenUser);
        } else {
            // 用工单位级别展示本用工单位的规则的使用人数
            number = selectCompanyUseCountEmpInfoListVOByRuleTypeAndSalaryCalculateRuleId(salaryCalculateRuleGroupListVO.getRuleType(),
                    salaryCalculateRuleGroupListVO.getId(), tokenUser);
        }
        salaryCalculateRuleGroupListVO.setUsePeopleNumber(number);
    }

    @Override
    public Page<EmpInfoVO> selectEmpInfoVoCompanyUse(SalaryCalculateRuleEmpInfoQuery salaryCalculateRuleEmpInfoQuery, TokenUser tokenUser) {
        // 查询规则
        String salaryCalculateRuleId = salaryCalculateRuleEmpInfoQuery.getSalaryCalculateRuleId();
        String nameOrIdCard = salaryCalculateRuleEmpInfoQuery.getNameOrIdCard();
        SalaryCalculateRuleGroupVO salaryCalculateRuleGroupVO = this.selectById(salaryCalculateRuleId,
                tokenUser.getSiteId());
        ParamException.notNull(salaryCalculateRuleGroupVO, "根据规则id没有找到该规则信息!");
        Integer ruleType = salaryCalculateRuleGroupVO.getRuleType();
        // 构建page
        return selectCompanyUsePageByRuleTypeAndSalaryCalculateRuleId(ruleType, salaryCalculateRuleId, nameOrIdCard,
                tokenUser, salaryCalculateRuleEmpInfoQuery.getPageNo(), salaryCalculateRuleEmpInfoQuery.getPageSize());
    }

    @Override
    public Page<EmpInfoVO> selectEmpInfoVoSiteUse(SalaryCalculateRuleEmpInfoQuery salaryCalculateRuleEmpInfoQuery, TokenUser tokenUser) {
        // 查询规则（查找来源是查询规则id的规则组）
        String salaryCalculateRuleGroupId = salaryCalculateRuleEmpInfoQuery.getSalaryCalculateRuleId();
        SalaryCalculateRuleGroupVO salaryCalculateRuleGroupVO = this.selectById(salaryCalculateRuleGroupId,
                tokenUser.getSiteId());
        ParamException.notNull(salaryCalculateRuleGroupVO, "规则不存在或已删除，请刷新重试");
        String nameOrIdCard = salaryCalculateRuleEmpInfoQuery.getNameOrIdCard();
        Integer ruleType = salaryCalculateRuleGroupVO.getRuleType();
        // 构建page
        return selectSiteUsePageByRuleTypeAndSalaryCalculateRuleId(ruleType, salaryCalculateRuleGroupId, nameOrIdCard,
                tokenUser, salaryCalculateRuleEmpInfoQuery.getPageNo(), salaryCalculateRuleEmpInfoQuery.getPageSize());
    }

    @Override
    public SalaryCalculateRuleGroupDO selectByCompanyIdAndName(String companyId, String name) {
        if (StrKit.isEmpty(companyId) || StrKit.isEmpty(name)) {
            throw new ParamException("用工单位id和名称都不能为空");
        }
        Example example = new Example(SalaryCalculateRuleGroupDO.class);
        example.and()
                .andEqualTo("companyId", companyId)
                .andEqualTo("name", name)
                .andEqualTo("valid", true);
        example.setOrderByClause("gmt_create desc");
        List<SalaryCalculateRuleGroupDO> salaryCalculateRuleGroupDOList = salaryCalculateRuleGroupDAO
                .selectByExample(example);
        if (CollectionUtils.isEmpty(salaryCalculateRuleGroupDOList)) {
            return null;
        }
        return salaryCalculateRuleGroupDOList.get(0);
    }

    @Override
    public List<SalaryCalculateRuleGroupDO> selectHadSourceByCompanyId(String companyId, TokenUser tokenUser) {
        Example example = new Example(SalaryCalculateRuleGroupDO.class);
        example.and()
                .andEqualTo("companyId", companyId)
                .andIsNotNull("source")
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true);
        return salaryCalculateRuleGroupDAO.selectByExample(example);
    }

    @Override
    public List<SalaryCalculateRuleGroupDO> selectBySource(String source, String siteId) {
        if (StrKit.isEmpty(source) || StrKit.isEmpty(siteId)) {
            return new ArrayList<>();
        }
        Example example = new Example(SalaryCalculateRuleGroupDO.class);
        example.and()
                .andEqualTo("source", source)
                .andEqualTo("siteId", siteId)
                .andEqualTo("valid", true);
        return salaryCalculateRuleGroupDAO.selectByExample(example);
    }

    private List<EmpInfoVO> selectSiteUseEmpInfoListVOByRuleTypeAndSalaryCalculateRuleId(Integer ruleType,
                                                                                         String salaryCalculateRuleGroupId,
                                                                                         String nameOrIdCard,
                                                                                         TokenUser tokenUser) {
        List<EmpInfoVO> empInfoVOList = new ArrayList<>();
        // 查询规则（查找来源是查询规则id的规则组）
        SalaryCalculateRuleGroupVO salaryCalculateRuleGroupVO = this.selectById(salaryCalculateRuleGroupId, tokenUser.getSiteId());
        ParamException.notNull(salaryCalculateRuleGroupVO, "规则不存在或已删除，请刷新重试");
        Example example = new Example(SalaryCalculateRuleGroupDO.class);
        example.and()
                .andEqualTo("source", salaryCalculateRuleGroupId)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());
        List<SalaryCalculateRuleGroupDO> salaryCalculateRuleGroupDOList = salaryCalculateRuleGroupDAO
                .selectByExample(example);
        if (CollectionUtils.isEmpty(salaryCalculateRuleGroupDOList)) {
            return empInfoVOList;
        }
        // 查询每个来源是租户的规则组的使用人员
        List<String> salaryCalculateRuleGroupIdList = salaryCalculateRuleGroupDOList.stream()
                .map(SalaryCalculateRuleGroupDO::getId).collect(Collectors.toList());
        Example exampleEmpInfo = new Example(EmpInfoDO.class);
        exampleEmpInfo.and()
                .andNotEqualTo("status", EmpInfoStatus.HAS_QUIT.getValue())
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true);
        // 根据条件查询员工信息
        if (StrKit.isNotEmpty(nameOrIdCard)) {
            exampleEmpInfo.and()
                    .orLike("name", "%" + nameOrIdCard + "%")
                    .orLike("idCard", "%" + nameOrIdCard + "%");
        }
        if (ruleType.equals(CalculatePayConstant.RULE_TYPE_COMMISSION)) {
            exampleEmpInfo.and().andIn("serviceFeeRuleId", salaryCalculateRuleGroupIdList);
        } else {
            exampleEmpInfo.and().andIn("salaryRuleId", salaryCalculateRuleGroupIdList);
        }
        exampleEmpInfo.setOrderByClause("gmt_create desc");
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(exampleEmpInfo);
        // 过滤手机号重复
        empInfoDOList = empInfoDOList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
                new TreeSet<>(Comparator.comparing(EmpInfoDO::getPhone))), ArrayList::new));
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return empInfoVOList;
        }
        // 添加用工单位名称
        empInfoDOList.forEach(empInfoDO -> {
            CompanyDO companyDO = companyService.selectDOById(empInfoDO.getCompanyId(), tokenUser.getSiteId());
            empInfoDO.setWorkingUnitName(companyDO != null ? companyDO.getName() : "查询不到该公司信息");
        });
        empInfoVOList = empInfoDOList.stream().map(empInfoDO -> empInfoDO.to(EmpInfoVO.class)).collect(Collectors.toList());
        // 添加渠道信息
        empInfoVOList.forEach(empInfoVO -> {
            // 根据手机号查询预登记人员
            CheckInPeopleDO checkInPeopleDO = checkInPeopleService.selectByPhone(empInfoVO.getPhone(), tokenUser.getSiteId());
            if (Objects.nonNull(checkInPeopleDO)) {
                empInfoVO.setChannelVO(channelService.selectById(checkInPeopleDO.getChannelId(), tokenUser.getSiteId()));
            }
        });
        return empInfoVOList;
    }

    private List<EmpInfoVO> selectCompanyUseEmpInfoListVOByRuleTypeAndSalaryCalculateRuleId(Integer ruleType,
                                                                                            String salaryCalculateRuleGroupId,
                                                                                            String nameOrIdCard,
                                                                                            TokenUser tokenUser) {
        List<EmpInfoVO> empInfoVOList = new ArrayList<>();
        // 查询规则
        SalaryCalculateRuleGroupVO salaryCalculateRuleGroupVO = this.selectById(salaryCalculateRuleGroupId, tokenUser.getSiteId());
        ParamException.notNull(salaryCalculateRuleGroupVO, "根据规则id没有找到该规则信息!");
        // 根据条件查询员工信息
        Example example = new Example(EmpInfoDO.class);
        if (ruleType.equals(CalculatePayConstant.RULE_TYPE_COMMISSION)) {
            example.and().andEqualTo("serviceFeeRuleId", salaryCalculateRuleGroupId);
        } else {
            example.and().andEqualTo("salaryRuleId", salaryCalculateRuleGroupId);
        }
        if (StrKit.isNotEmpty(nameOrIdCard)) {
            example.and()
                    .orLike("name", "%" + nameOrIdCard + "%")
                    .orLike("idCard", "%" + nameOrIdCard + "%");
        }
        example.and()
                .andNotEqualTo("status", EmpInfoStatus.HAS_QUIT.getValue())
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true);
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        // 过滤重复及离职的员工
        // 根据手机号过滤
        empInfoDOList = empInfoDOList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
                new TreeSet<>(Comparator.comparing(EmpInfoDO::getPhone))), ArrayList::new));
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return empInfoVOList;
        }
        // 添加用工单位名称
        empInfoDOList.forEach(empInfoDO -> {
            CompanyDO companyDO = companyService.selectDOById(empInfoDO.getCompanyId(), tokenUser.getSiteId());
            empInfoDO.setWorkingUnitName(companyDO != null ? companyDO.getName() : "查询不到该公司信息");
        });
        empInfoVOList = empInfoDOList.stream().map(empInfoDO -> empInfoDO.to(EmpInfoVO.class)).collect(Collectors.toList());
        // 添加渠道信息
        empInfoVOList.forEach(empInfoVO -> {
            // 根据手机号查询预登记人员
            CheckInPeopleDO checkInPeopleDO = checkInPeopleService.selectByPhone(empInfoVO.getPhone(), tokenUser.getSiteId());
            if (Objects.nonNull(checkInPeopleDO)) {
                empInfoVO.setChannelVO(channelService.selectById(checkInPeopleDO.getChannelId(), tokenUser.getSiteId()));
            }
        });
        return empInfoVOList;
    }

    private int selectSiteUseCountEmpInfoListVOByRuleTypeAndSalaryCalculateRuleId(Integer ruleType,
                                                                                  String salaryCalculateRuleGroupId,
                                                                                  TokenUser tokenUser) {
        // 查询规则（查找来源是查询规则id的规则组）
        SalaryCalculateRuleGroupVO salaryCalculateRuleGroupVO = this.selectById(salaryCalculateRuleGroupId, tokenUser.getSiteId());
        ParamException.notNull(salaryCalculateRuleGroupVO, "规则不存在或已删除，请刷新重试");
        Example example = new Example(SalaryCalculateRuleGroupDO.class);
        example.and()
                .andEqualTo("source", salaryCalculateRuleGroupId)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());
        List<SalaryCalculateRuleGroupDO> salaryCalculateRuleGroupDOList = salaryCalculateRuleGroupDAO
                .selectByExample(example);
        if (CollectionUtils.isEmpty(salaryCalculateRuleGroupDOList)) {
            return 0;
        }
        // 查询每个来源是租户的规则组的使用人员
        List<String> salaryCalculateRuleGroupIdList = salaryCalculateRuleGroupDOList.stream()
                .map(SalaryCalculateRuleGroupDO::getId).collect(Collectors.toList());
        Example exampleEmpInfo = new Example(EmpInfoDO.class);
        exampleEmpInfo.and()
                .andNotEqualTo("status", EmpInfoStatus.HAS_QUIT.getValue())
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true);
        // 根据条件查询员工信息
        if (ruleType.equals(CalculatePayConstant.RULE_TYPE_COMMISSION)) {
            exampleEmpInfo.and().andIn("serviceFeeRuleId", salaryCalculateRuleGroupIdList);
        } else {
            exampleEmpInfo.and().andIn("salaryRuleId", salaryCalculateRuleGroupIdList);
        }
        exampleEmpInfo.setOrderByClause("gmt_create desc");
        return empInfoDAO.selectCountByExample(exampleEmpInfo);
    }

    private int selectCompanyUseCountEmpInfoListVOByRuleTypeAndSalaryCalculateRuleId(Integer ruleType,
                                                                                     String salaryCalculateRuleGroupId,
                                                                                     TokenUser tokenUser) {
        // 查询规则
        SalaryCalculateRuleGroupVO salaryCalculateRuleGroupVO = this.selectById(salaryCalculateRuleGroupId, tokenUser.getSiteId());
        ParamException.notNull(salaryCalculateRuleGroupVO, "根据规则id没有找到该规则信息!");
        // 根据条件查询员工信息
        Example example = new Example(EmpInfoDO.class);
        if (ruleType.equals(CalculatePayConstant.RULE_TYPE_COMMISSION)) {
            example.and().andEqualTo("serviceFeeRuleId", salaryCalculateRuleGroupId);
        } else {
            example.and().andEqualTo("salaryRuleId", salaryCalculateRuleGroupId);
        }
        example.and()
                .andNotEqualTo("status", EmpInfoStatus.HAS_QUIT.getValue())
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true);
        return empInfoDAO.selectCountByExample(example);
    }

    private Page<EmpInfoVO> selectSiteUsePageByRuleTypeAndSalaryCalculateRuleId(Integer ruleType,
                                                                                String salaryCalculateRuleGroupId,
                                                                                String nameOrIdCard,
                                                                                TokenUser tokenUser,
                                                                                int pageNo, int pageSize) {
        List<EmpInfoVO> empInfoVOList;
        // 查询规则（查找来源是查询规则id的规则组）
        SalaryCalculateRuleGroupVO salaryCalculateRuleGroupVO = this.selectById(salaryCalculateRuleGroupId, tokenUser.getSiteId());
        ParamException.notNull(salaryCalculateRuleGroupVO, "规则不存在或已删除，请刷新重试");
        Example example = new Example(SalaryCalculateRuleGroupDO.class);
        example.and()
                .andEqualTo("source", salaryCalculateRuleGroupId)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());
        List<SalaryCalculateRuleGroupDO> salaryCalculateRuleGroupDOList = salaryCalculateRuleGroupDAO
                .selectByExample(example);
        if (CollectionUtils.isEmpty(salaryCalculateRuleGroupDOList)) {
            return new Page<>(pageSize, pageNo, 0);
        }
        // 查询每个来源是租户的规则组的使用人员
        List<String> salaryCalculateRuleGroupIdList = salaryCalculateRuleGroupDOList.stream()
                .map(SalaryCalculateRuleGroupDO::getId).collect(Collectors.toList());
        Example exampleEmpInfo = new Example(EmpInfoDO.class);
        exampleEmpInfo.and()
                .andNotEqualTo("status", EmpInfoStatus.HAS_QUIT.getValue())
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true);
        // 根据条件查询员工信息
        if (StrKit.isNotEmpty(nameOrIdCard)) {
            exampleEmpInfo.and()
                    .orLike("name", "%" + nameOrIdCard + "%")
                    .orLike("idCard", "%" + nameOrIdCard + "%");
        }
        if (ruleType.equals(CalculatePayConstant.RULE_TYPE_COMMISSION)) {
            exampleEmpInfo.and().andIn("serviceFeeRuleId", salaryCalculateRuleGroupIdList);
        } else {
            exampleEmpInfo.and().andIn("salaryRuleId", salaryCalculateRuleGroupIdList);
        }
        exampleEmpInfo.setOrderByClause("gmt_create desc");
        Page<EmpInfoDO> empInfoDOPage = empInfoDAO.selectPageByExample(exampleEmpInfo, pageNo, pageSize);
        if (CollectionUtils.isEmpty(empInfoDOPage.getEntities())) {
            return new Page<>( pageSize, pageNo, 0);
        }
        // 添加用工单位名称
        empInfoDOPage.getEntities().forEach(empInfoDO -> {
            CompanyDO companyDO = companyService.selectDOById(empInfoDO.getCompanyId(), tokenUser.getSiteId());
            empInfoDO.setWorkingUnitName(companyDO != null ? companyDO.getName() : "查询不到该公司信息");
        });
        empInfoVOList = empInfoDOPage.getEntities().stream().map(empInfoDO -> empInfoDO.to(EmpInfoVO.class)).collect(Collectors.toList());
        // 添加渠道信息
        empInfoVOList.forEach(empInfoVO -> {
            // 根据手机号查询预登记人员
            CheckInPeopleDO checkInPeopleDO = checkInPeopleService.selectByPhone(empInfoVO.getPhone(), tokenUser.getSiteId());
            if (Objects.nonNull(checkInPeopleDO)) {
                empInfoVO.setChannelVO(channelService.selectById(checkInPeopleDO.getChannelId(), tokenUser.getSiteId()));
            }
        });
        return  new Page<>(empInfoVOList, pageNo, pageSize, empInfoDOPage.getEntityCount());
    }

    private Page<EmpInfoVO> selectCompanyUsePageByRuleTypeAndSalaryCalculateRuleId(Integer ruleType,
                                                                                   String salaryCalculateRuleGroupId,
                                                                                   String nameOrIdCard,
                                                                                   TokenUser tokenUser,
                                                                                   int pageNo, int pageSize) {
        List<EmpInfoVO> empInfoVOList;
        // 查询规则
        SalaryCalculateRuleGroupVO salaryCalculateRuleGroupVO = this.selectById(salaryCalculateRuleGroupId, tokenUser.getSiteId());
        ParamException.notNull(salaryCalculateRuleGroupVO, "根据规则id没有找到该规则信息!");
        // 根据条件查询员工信息
        Example example = new Example(EmpInfoDO.class);
        if (ruleType.equals(CalculatePayConstant.RULE_TYPE_COMMISSION)) {
            example.and().andEqualTo("serviceFeeRuleId", salaryCalculateRuleGroupId);
        } else {
            example.and().andEqualTo("salaryRuleId", salaryCalculateRuleGroupId);
        }
        if (StrKit.isNotEmpty(nameOrIdCard)) {
            example.and()
                    .orLike("name", "%" + nameOrIdCard + "%")
                    .orLike("idCard", "%" + nameOrIdCard + "%");
        }
        example.and()
                .andNotEqualTo("status", EmpInfoStatus.HAS_QUIT.getValue())
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true);
        Page<EmpInfoDO> empInfoDOPage = empInfoDAO.selectPageByExample(example, pageNo, pageSize);
        if (CollectionUtils.isEmpty(empInfoDOPage.getEntities())) {
            return new Page<>( pageSize, pageNo, 0);
        }
        // 添加用工单位名称
        empInfoDOPage.getEntities().forEach(empInfoDO -> {
            CompanyDO companyDO = companyService.selectDOById(empInfoDO.getCompanyId(), tokenUser.getSiteId());
            empInfoDO.setWorkingUnitName(companyDO != null ? companyDO.getName() : "查询不到该公司信息");
        });
        empInfoVOList = empInfoDOPage.getEntities().stream().map(empInfoDO -> empInfoDO.to(EmpInfoVO.class))
                .collect(Collectors.toList());
        // 添加渠道信息
        empInfoVOList.forEach(empInfoVO -> {
            // 根据手机号查询预登记人员
            CheckInPeopleDO checkInPeopleDO = checkInPeopleService.selectByPhone(empInfoVO.getPhone(), tokenUser.getSiteId());
            if (Objects.nonNull(checkInPeopleDO)) {
                empInfoVO.setChannelVO(channelService.selectById(checkInPeopleDO.getChannelId(), tokenUser.getSiteId()));
            }
        });
        return  new Page<>(empInfoVOList, pageNo, pageSize, empInfoDOPage.getEntityCount());
    }


    /**
     * 根据查询参数，构建example
     *
     * @param salaryCalculateRuleGroupQuery 查询参数
     * @param siteId                        所属站点id
     * @return example
     */
    private Example buildExample(SalaryCalculateRuleGroupQuery salaryCalculateRuleGroupQuery, String siteId) {
        Example example = new Example(SalaryCalculateRuleGroupDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        if (salaryCalculateRuleGroupQuery.getRuleType() != null) {
            example.and().andEqualTo("ruleType", salaryCalculateRuleGroupQuery.getRuleType());
        }
        if (salaryCalculateRuleGroupQuery.getName() != null) {
            example.and().andLike("name", "%" + salaryCalculateRuleGroupQuery.getName() + "%");
        }
        if (salaryCalculateRuleGroupQuery.getCompanyId() != null) {
            example.and().andEqualTo("companyId", salaryCalculateRuleGroupQuery.getCompanyId());
        }
        if (salaryCalculateRuleGroupQuery.getSource() != null) {
            example.and().andEqualTo("source", salaryCalculateRuleGroupQuery.getSource());
        }
        // 排序
        ExampleKit.setExampleOrder(example, salaryCalculateRuleGroupQuery.getOrders());
        return example;
    }
}




